Skip to main content

How JWT validates token (tampered or not) when user send via Requests



JWT (JSON Web Token) is a widely-used standard for secure user authentication in web applications. It allows servers to authenticate users using a signed token that contains user information. But how does the system validate whether the token is authentic and hasn't been tampered with? In this blog, we will explain the detailed process of how a JWT token is validated and how the system knows whether a token is valid or generated by it.

Key Concepts of JWT Authentication

Before diving into token validation, it’s essential to understand the structure and components of a JWT token.

JWT Structure

A JWT token consists of three parts:

  1. Header: Contains metadata, including the algorithm used for signing the token (e.g., HS256 for HMAC SHA-256).
  2. Payload: Contains the claims, or user information, such as user ID, username, and roles.
  3. Signature: Used to verify that the token hasn’t been tampered with. It is generated by signing the header and payload using a secret key or private key.

Each part is base64-encoded and separated by dots (.). For example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

In this token:

  • The first part (header) is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
  • The second part (payload) is eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
  • The third part (signature) is SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c.

Now, let’s explore how the system validates whether this token is genuine.

JWT Token Validation Process

Step 1: User Logs In and JWT Token is Issued

The user provides valid login credentials (e.g., username and password), and the system authenticates the user using a database or other user store. After successful authentication, the system generates a JWT token for the user.

Here’s an example of how the token is generated in a .NET Core application:

public string GenerateJwtToken(User user)
{
    var claims = new List<Claim>
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
        new Claim(JwtRegisteredClaimNames.Name, user.Username),
        new Claim(ClaimTypes.Role, user.Role)
    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKeyHere"));
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: "yourapp",
        audience: "yourapp",
        claims: claims,
        expires: DateTime.Now.AddMinutes(30),
        signingCredentials: creds
    );

    return new JwtSecurityTokenHandler().WriteToken(token);
}

Here’s what happens during this step:

  • The claims include information about the user (user.Id, user.Username, and user.Role).
  • The secret key is used to sign the token with the HMAC SHA-256 algorithm (SecurityAlgorithms.HmacSha256).
  • The JWT token is generated and returned to the user.

Step 2: User Makes API Requests with the JWT Token

After the token is generated, it is sent to the client (e.g., in the response body or HTTP headers). For subsequent API requests, the user includes this token in the Authorization header as a Bearer token.

Example of an API request with a JWT token:

GET /api/products
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Step 3: Token Validation on the Server

When the server receives a request with a JWT token, it needs to validate the token to ensure it is:

  1. Authentic (signed by the server).
  2. Untampered (not modified by anyone after it was issued).
  3. Not expired.

Step 3.1: Parse the Token

The server extracts the token from the Authorization header and parses it.

var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.ReadJwtToken(tokenString);

Step 3.2: Verify the Signature

To validate the token, the server must verify the signature. The signature is what ensures the token has not been tampered with after it was issued. The server uses the secret key that was used to sign the token when it was created.

var tokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKeyHere")),
    ValidateIssuer = true,
    ValidateAudience = true,
    ValidIssuer = "yourapp",
    ValidAudience = "yourapp",
    ValidateLifetime = true,  // Ensure the token is not expired
    ClockSkew = TimeSpan.Zero
};

SecurityToken validatedToken;
var principal = tokenHandler.ValidateToken(tokenString, tokenValidationParameters, out validatedToken);
Here’s what happens during validation:
  • ValidateIssuerSigningKey: The server ensures that the signature was generated using the correct secret key. If someone tries to modify the token, the signature validation will fail.
  • Issuer and Audience: The server checks that the token was issued by the correct issuer and for the correct audience.
  • ValidateLifetime: Ensures that the token hasn’t expired. Tokens typically have an expiration time (exp claim), and this check ensures that old tokens aren’t accepted.

Step 3.3: Verify Claims

The server also validates the claims within the token, such as the user’s ID, roles, and any other custom claims.

var userId = principal.FindFirst(JwtRegisteredClaimNames.Sub)?.Value;
var username = principal.FindFirst(JwtRegisteredClaimNames.Name)?.Value;
var role = principal.FindFirst(ClaimTypes.Role)?.Value;

// You can further check if the user has the necessary roles to access the resource

If all these checks pass, the token is considered valid, and the request proceeds.

Example of Token Validation in Action

Let’s see an example flow of how a token validation process works in a real-world scenario.

1. User Logs In

The user provides valid credentials, and the system generates a JWT token for the user:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

2. User Makes a Request with the Token

The user sends the JWT token in the Authorization header:

GET /api/orders
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

3. Server Validates the Token

The server receives the request and performs the following checks:

  1. Signature Validation: The signature is validated using the secret key.
  2. Expiration Check: The server ensures the token is still valid based on its expiration time.
  3. Claim Validation: The server extracts the claims from the token and validates the user’s identity.

If the token is valid, the server processes the request and responds with the requested data. If the token is invalid or expired, the server returns an error (e.g., 401 Unauthorized).


Why is JWT Token Secure?

1. Digital Signature

The core security feature of a JWT token is its digital signature. This signature ensures the token cannot be modified without the server knowing. When the server issues a token, it signs it with a secret key, and that same key is required to validate the signature. Anyone who tries to modify the token will invalidate the signature.

2. No Server-Side Storage Required

Unlike session-based authentication, JWT tokens do not require server-side storage. The token itself contains all the information needed, and the server only needs to validate it using the secret key.

3. Short-Lived Tokens

JWT tokens are typically short-lived, and once they expire, the user must re-authenticate to receive a new token. This ensures that even if a token is compromised, it can only be used for a limited time.

Conclusion

In this blog, we’ve explored how JWT tokens are validated and how the system knows a token is valid. The validation process involves verifying the token’s signature, claims, and expiration. By using a secret key to sign tokens and short-lived expiration periods, JWT tokens provide a secure and stateless way to authenticate users in modern web applications.

JWT is widely used in distributed systems and microservices due to its efficiency and security, as it eliminates the need for server-side session storage and offers strong integrity protection via cryptographic signatures.

Comments

Popular posts from this blog

Implementing and Integrating RabbitMQ in .NET Core Application: Shopping Cart and Order API

RabbitMQ is a robust message broker that enables communication between services in a decoupled, reliable manner. In this guide, we’ll implement RabbitMQ in a .NET Core application to connect two microservices: Shopping Cart API (Producer) and Order API (Consumer). 1. Prerequisites Install RabbitMQ locally or on a server. Default Management UI: http://localhost:15672 Default Credentials: guest/guest Install the RabbitMQ.Client package for .NET: dotnet add package RabbitMQ.Client 2. Architecture Overview Shopping Cart API (Producer): Sends a message when a user places an order. RabbitMQ : Acts as the broker to hold the message. Order API (Consumer): Receives the message and processes the order. 3. RabbitMQ Producer: Shopping Cart API Step 1: Install RabbitMQ.Client Ensure the RabbitMQ client library is installed: dotnet add package RabbitMQ.Client Step 2: Create the Producer Service Add a RabbitMQProducer class to send messages. RabbitMQProducer.cs : using RabbitMQ.Client; usin...

How Does My .NET Core Application Build Once and Run Everywhere?

One of the most powerful features of .NET Core is its cross-platform nature. Unlike the traditional .NET Framework, which was limited to Windows, .NET Core allows you to build your application once and run it on Windows , Linux , or macOS . This makes it an excellent choice for modern, scalable, and portable applications. In this blog, we’ll explore how .NET Core achieves this, the underlying architecture, and how you can leverage it to make your applications truly cross-platform. Key Features of .NET Core for Cross-Platform Development Platform Independence : .NET Core Runtime is available for multiple platforms (Windows, Linux, macOS). Applications can run seamlessly without platform-specific adjustments. Build Once, Run Anywhere : Compile your code once and deploy it on any OS with minimal effort. Self-Contained Deployment : .NET Core apps can include the runtime in the deployment package, making them independent of the host system's installed runtime. Standardized Libraries ...

Clean Architecture: What It Is and How It Differs from Microservices

In the tech world, buzzwords like   Clean Architecture   and   Microservices   often dominate discussions about building scalable, maintainable applications. But what exactly is Clean Architecture? How does it compare to Microservices? And most importantly, is it more efficient? Let’s break it all down, from understanding the core principles of Clean Architecture to comparing it with Microservices. By the end of this blog, you’ll know when to use each and why Clean Architecture might just be the silent hero your projects need. What is Clean Architecture? Clean Architecture  is a design paradigm introduced by Robert C. Martin (Uncle Bob) in his book  Clean Architecture: A Craftsman’s Guide to Software Structure and Design . It’s an evolution of layered architecture, focusing on organizing code in a way that makes it  flexible ,  testable , and  easy to maintain . Core Principles of Clean Architecture Dependency Inversion : High-level modules s...